<template>
  <div class="attachment-upload-form">
    <h3 class="section-title">附件上传</h3>
    
    <div class="upload-area">
      <el-upload
        ref="uploadRef"
        class="upload-dragger"
        drag
        multiple
        :auto-upload="false"
        :on-change="handleFileChange"
        :on-remove="handleFileRemove"
        :before-upload="beforeUpload"
        :file-list="fileList"
        accept=".pdf,.doc,.docx,.jpg,.jpeg,.png,.gif,.mp4,.avi,.mov"
      >
        <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
        <div class="el-upload__text">
          将文件拖到此处，或<em>点击上传</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            支持格式：PDF、Word、图片、视频<br>
            文件大小限制：图片≤5MB，视频≤50MB，文档≤10MB
          </div>
        </template>
      </el-upload>
    </div>
    
    <div v-if="fileList.length > 0" class="file-list">
      <h4 class="file-list-title">已上传文件</h4>
      <div class="file-items">
        <div 
          v-for="(file, index) in fileList" 
          :key="file.uid"
          class="file-item"
        >
          <div class="file-info">
            <el-icon class="file-icon" :class="getFileIcon(file.name)">
              <Document v-if="isDocument(file.name)" />
              <Picture v-else-if="isImage(file.name)" />
              <VideoPlay v-else-if="isVideo(file.name)" />
              <Document v-else />
            </el-icon>
            <div class="file-details">
              <div class="file-name">
                <span v-if="!file.isRenaming" @click="startRename(index)">
                  {{ file.name }}
                </span>
                <el-input
                  v-else
                  v-model="file.newName"
                  size="small"
                  @blur="finishRename(index)"
                  @keyup.enter="finishRename(index)"
                  @keyup.esc="cancelRename(index)"
                  ref="renameInput"
                />
              </div>
              <div class="file-meta">
                {{ formatFileSize(file.size) }} | {{ file.type }}
              </div>
            </div>
          </div>
          <div class="file-actions">
            <el-button 
              type="text" 
              size="small" 
              @click="startRename(index)"
              :disabled="file.isRenaming"
            >
              <el-icon><Edit /></el-icon>
              重命名
            </el-button>
            <el-button 
              type="text" 
              size="small" 
              @click="previewFile(file)"
            >
              <el-icon><View /></el-icon>
              预览
            </el-button>
            <el-button 
              type="text" 
              size="small" 
              @click="removeFile(index)"
              class="delete-btn"
            >
              <el-icon><Delete /></el-icon>
              删除
            </el-button>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 文件预览对话框 -->
    <el-dialog
      v-model="previewVisible"
      title="文件预览"
      width="60%"
      :before-close="closePreview"
    >
      <div class="preview-content">
        <img 
          v-if="previewFileType === 'image'" 
          :src="previewUrl" 
          style="max-width: 100%; height: auto;"
        />
        <video 
          v-else-if="previewFileType === 'video'" 
          :src="previewUrl" 
          controls 
          style="max-width: 100%;"
        />
        <iframe 
          v-else-if="previewFileType === 'pdf'" 
          :src="previewUrl" 
          width="100%" 
          height="500px"
        />
        <div v-else class="preview-placeholder">
          <el-icon><Document /></el-icon>
          <p>此文件类型暂不支持预览</p>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { 
  UploadFilled, Document, Picture, VideoPlay, Edit, View, Delete 
} from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'

export default {
  name: 'AttachmentUpload',
  components: { 
    UploadFilled, Document, Picture, VideoPlay, Edit, View, Delete 
  },
  props: {
    modelValue: {
      type: Array,
      default: () => []
    }
  },
  emits: ['update:modelValue'],
  data() {
    return {
      fileList: [...this.modelValue],
      previewVisible: false,
      previewUrl: '',
      previewFileType: ''
    }
  },
  watch: {
    modelValue: {
      handler(newVal) {
        this.fileList = [...newVal]
      },
      deep: true
    },
    fileList: {
      handler(newVal) {
        this.$emit('update:modelValue', newVal)
      },
      deep: true
    }
  },
  methods: {
    beforeUpload(file) {
      // 检查文件大小
      const maxSize = this.getMaxFileSize(file.name)
      if (file.size > maxSize) {
        ElMessage.error(`文件大小不能超过 ${this.formatFileSize(maxSize)}`)
        return false
      }
      
      // 检查文件类型
      if (!this.isValidFileType(file.name)) {
        ElMessage.error('不支持的文件类型')
        return false
      }
      
      return false // 阻止自动上传
    },
    
    handleFileChange(file, fileList) {
      this.fileList = fileList.map(f => ({
        ...f,
        isRenaming: false,
        newName: f.name
      }))
    },
    
    handleFileRemove(file, fileList) {
      this.fileList = fileList
    },
    
    removeFile(index) {
      this.fileList.splice(index, 1)
    },
    
    startRename(index) {
      this.fileList[index].isRenaming = true
      this.$nextTick(() => {
        if (this.$refs.renameInput && this.$refs.renameInput[0]) {
          this.$refs.renameInput[0].focus()
        }
      })
    },
    
    finishRename(index) {
      const file = this.fileList[index]
      if (file.newName && file.newName.trim()) {
        file.name = file.newName.trim()
      }
      file.isRenaming = false
    },
    
    cancelRename(index) {
      this.fileList[index].isRenaming = false
      this.fileList[index].newName = this.fileList[index].name
    },
    
    previewFile(file) {
      this.previewUrl = URL.createObjectURL(file.raw)
      this.previewFileType = this.getFileType(file.name)
      this.previewVisible = true
    },
    
    closePreview() {
      this.previewVisible = false
      if (this.previewUrl) {
        URL.revokeObjectURL(this.previewUrl)
        this.previewUrl = ''
      }
    },
    
    getMaxFileSize(fileName) {
      if (this.isImage(fileName)) return 5 * 1024 * 1024 // 5MB
      if (this.isVideo(fileName)) return 50 * 1024 * 1024 // 50MB
      if (this.isDocument(fileName)) return 10 * 1024 * 1024 // 10MB
      return 5 * 1024 * 1024 // 默认5MB
    },
    
    isValidFileType(fileName) {
      const validExtensions = [
        '.pdf', '.doc', '.docx', '.jpg', '.jpeg', '.png', '.gif', '.mp4', '.avi', '.mov'
      ]
      const extension = fileName.toLowerCase().substring(fileName.lastIndexOf('.'))
      return validExtensions.includes(extension)
    },
    
    isImage(fileName) {
      const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif']
      const extension = fileName.toLowerCase().substring(fileName.lastIndexOf('.'))
      return imageExtensions.includes(extension)
    },
    
    isVideo(fileName) {
      const videoExtensions = ['.mp4', '.avi', '.mov']
      const extension = fileName.toLowerCase().substring(fileName.lastIndexOf('.'))
      return videoExtensions.includes(extension)
    },
    
    isDocument(fileName) {
      const documentExtensions = ['.pdf', '.doc', '.docx']
      const extension = fileName.toLowerCase().substring(fileName.lastIndexOf('.'))
      return documentExtensions.includes(extension)
    },
    
    getFileIcon(fileName) {
      if (this.isImage(fileName)) return 'image-icon'
      if (this.isVideo(fileName)) return 'video-icon'
      return 'document-icon'
    },
    
    getFileType(fileName) {
      if (this.isImage(fileName)) return 'image'
      if (this.isVideo(fileName)) return 'video'
      if (fileName.toLowerCase().endsWith('.pdf')) return 'pdf'
      return 'other'
    },
    
    formatFileSize(bytes) {
      if (bytes === 0) return '0 B'
      const k = 1024
      const sizes = ['B', 'KB', 'MB', 'GB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    }
  }
}
</script>

<style scoped>
.attachment-upload-form {
  margin-bottom: 24px;
}

.section-title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 16px;
  padding-bottom: 8px;
  border-bottom: 2px solid #409eff;
}

.upload-area {
  margin-bottom: 20px;
}

.upload-dragger {
  width: 100%;
}

.file-list {
  border-top: 1px solid #e4e7ed;
  padding-top: 20px;
}

.file-list-title {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 16px;
}

.file-items {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.file-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  background: #fafafa;
}

.file-info {
  display: flex;
  align-items: center;
  flex: 1;
}

.file-icon {
  font-size: 20px;
  margin-right: 12px;
  color: #409eff;
}

.file-details {
  flex: 1;
}

.file-name {
  font-weight: 500;
  color: #303133;
  margin-bottom: 4px;
  cursor: pointer;
}

.file-name:hover {
  color: #409eff;
}

.file-meta {
  font-size: 12px;
  color: #909399;
}

.file-actions {
  display: flex;
  gap: 8px;
}

.delete-btn {
  color: #f56c6c;
}

.delete-btn:hover {
  color: #f78989;
}

.preview-content {
  text-align: center;
}

.preview-placeholder {
  padding: 40px;
  color: #909399;
}

.preview-placeholder .el-icon {
  font-size: 48px;
  margin-bottom: 16px;
}
</style> 